package com.bac.rentmap.ad.flat.search;

import java.io.Serializable;
import java.lang.reflect.InvocationTargetException;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.datanucleus.util.StringUtils;

import com.bac.rentmap.ad.flat.Constants;
import com.bac.rentmap.ad.flat.FlatAd;

/**
 * Parameters used for {@link FlatAd} searching.
 * 
 * @author Andrew Osipenko
 */
public class SearchParameters implements Serializable {
	private static final long serialVersionUID = -327998141125888135L;

	private String city = Constants.DEFAULT_CITY;

	/**
	 * Defines minimum price bound.
	 */
	private Integer minPrice;
	/**
	 * Defines minimum price bound.
	 */
	private Integer maxPrice;
	/**
	 * Used for distance sorting.
	 */
	private Double lat;
	/**
	 * Used for distance sorting.
	 */
	private Double lon;
	/**
	 * {@link Constants.ROOM_MARKER} or "1", "2", ...
	 */
	private String room;

	private Integer page = 0;

	private Integer pageSize;
	
	private String sourceUrl;

	public Integer getMinPrice() {
		return minPrice;
	}

	public void setMinPrice(Integer minPrice) {
		this.minPrice = minPrice;
	}

	public Integer getMaxPrice() {
		return maxPrice;
	}

	public void setMaxPrice(Integer maxPrice) {
		this.maxPrice = maxPrice;
	}

	public Double getLat() {
		return lat;
	}

	public Double getLon() {
		return lon;
	}

	public void setLat(Double lat) {
		this.lat = lat;
	}

	public void setLon(Double lon) {
		this.lon = lon;
	}

	public String getRoom() {
		return room;
	}

	public void setRoom(String room) {
		if (StringUtils.isEmpty(room))
			this.room = null;
		else
			this.room = room;
	}

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

	public Integer getPage() {
		return page;
	}

	public void setPage(Integer page) {
		this.page = page;
	}

	@Override
	public String toString() {
		try {
			return BeanUtils.describe(this).toString();
		} catch (IllegalAccessException e) {
			throw new RuntimeException(e);
		} catch (InvocationTargetException e) {
			throw new RuntimeException(e);
		} catch (NoSuchMethodException e) {
			throw new RuntimeException(e);
		}
	}

	public Integer getPageSize() {
		return pageSize;
	}

	public void setPageSize(Integer pageSize) {
		this.pageSize = pageSize;
	}

	@Override
	public int hashCode() {
		return describe().hashCode();
	}

	@Override
	public boolean equals(Object obj) {
		if (!(obj instanceof SearchParameters))
			return false;

		return describe().equals(((SearchParameters) obj).describe());
	}

	@SuppressWarnings({ "rawtypes", "unchecked" })
	private Map describe() {
		try {
			Map res = new HashMap(BeanUtils.describe(this));
			res.remove("class");
			return res;
		} catch (Exception e) {
			throw new RuntimeException("Failed to compare", e);
		}
	}

    public String getSourceUrl() {
        return sourceUrl;
    }

    public void setSourceUrl(String sourceUrl) {
        this.sourceUrl = sourceUrl;
    }
}
